package com.scs.application.modules.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.entity.FlowEntity;
import com.scs.application.core.flow.FlowContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.sys.entity.FlowExecution;
import com.scs.application.modules.sys.mapper.FlowExecutionMapper;
import com.scs.application.modules.sys.service.FlowExecutionService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 */
@Service
public class FlowExecutionServiceImpl extends BaseServiceImpl<FlowExecutionMapper, FlowExecution> implements FlowExecutionService {

    /**
    * @Description： 根据业务id获取流程实例，不存在则创建，独立事务
    * @Author wyt
    * @Date 2021/12/24
    */
    @Override
//    @Transactional(rollbackFor = Exception.class,propagation= Propagation.REQUIRES_NEW)
    public List<FlowExecution> getByBusIdsWithCreate(List<FlowEntity> flowEntityList, FlowContext flowContext) {
        List<String> busIdList = flowEntityList.stream().map(FlowEntity::getId).collect(Collectors.toList());
        List<FlowExecution> flowExecutionList = (List<FlowExecution>) this.listByIds(busIdList);
        if (flowExecutionList != null && flowExecutionList.size() == busIdList.size()) return flowExecutionList;
        if (flowExecutionList == null) {
            flowExecutionList = new ArrayList<FlowExecution>();
        }


        if (flowExecutionList.size() != busIdList.size()) {
            List<String> busIdListExist = flowExecutionList.stream().map(FlowExecution::getBusId).collect(Collectors.toList());
            List<FlowExecution> flowExecutionListSave = new ArrayList<FlowExecution>();
            Date now = DateUtils.now();
            busIdList.stream().filter(tmp -> !busIdListExist.contains(tmp)).forEach((busId) -> {
                FlowEntity flowEntity = flowEntityList.get(flowExecutionListSave.size());
                FlowExecution flowExecution = new FlowExecution();
                flowExecution.setId(busId);
                flowExecution.setBusId(busId).setBusKey(this.getBusKeyFromFlowEntity(flowEntity)).setBusTable(flowContext.getBusTable());
                flowExecution.setBusDate(now).setBusUser(UserUtils.currentUser().getName()).setBusTypeName(flowContext.getBusTypeName());

                //流程信息
                flowExecution.setFlowName(flowContext.getFlow().getName()).setFlowKey(flowContext.getFlow().getCode());

                flowExecution.setFlowStatus(flowEntity.getFlowStatus()).setFlowStatusText(flowContext.getFlowStatusTextTo());
                flowExecutionListSave.add(flowExecution);
            });
            this.saveBatch(flowExecutionListSave);
            flowExecutionList.addAll(flowExecutionListSave);
        }
        return flowExecutionList;
    }

    //获取业务单号
    private String getBusKeyFromFlowEntity(FlowEntity flowEntity) {
        JSONObject json = JSONObject.parseObject(JSON.toJSONString(flowEntity));
        for(String keyName : GlobalConsts.Spd.busKeyNameList) {
            if (json.containsKey(keyName)){
                return  json.getString(keyName);
            }
        }
//        throw ValidException.inst("解析流程对象失败，未找到有效单号字段");
        return "未知单号";
    }

    /**
     * @Description： 根据业务id获取流程实例，不存在则创建，独立事务
     * @Author wyt
     * @Date 2021/12/24
     */
    @Override
    public FlowExecution getByBusIdWithCreate(FlowEntity flowEntity, FlowContext flowContext) {
        FlowExecution flowExecution = this.getById(flowEntity.getId());
        if (flowExecution != null) {
            return  flowExecution;
        }
        return this.getByBusIdsWithCreate(Arrays.asList(flowEntity),flowContext).get(0);
    }
}
